/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package yuhuibear.poat.util;

import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import yuhuibear.poat.util.sqlParse.SqlSentence;

/**
 * 
 * @author yuhuibear
 */
public abstract class NameConvertor {

	public static String toTableName(Class<?> type) {
		String name = type.getName();
		if (name.length() < 1) { return name; }
		name = name.replaceAll(".*\\.", "");
		return toTableName(name).trim() + "s";
	}

	/**
	 * User.idTest => user.id_test
	 * 
	 * @param name
	 * @return
	 */
	public static String toTableName(String name) {

		if (name == null || name.length() < 1) { return name; }
		char fst = name.charAt(0);
		if (Character.isUpperCase(fst)) {
			name = Character.toLowerCase(fst) + name.substring(1);
		}
		StringBuffer str = new StringBuffer();
		int lastp = 0;
		boolean inQuote = false;
		boolean startWithLetter = false;
		char prvch = ' ';
		for (int i = 0; i < name.length(); i++) {
			Character ch = name.charAt(i);
			if (ch == '\'') {
				inQuote = !inQuote;
			}
			else if (prvch == ' ' && !inQuote) {
				if (Character.isLetter(ch)) {
					startWithLetter = true;
				}
				else {
					startWithLetter = false;
				}
			}
			if (!inQuote) {
				if (Character.isUpperCase(ch)) {
					str.append(name.substring(lastp, i));
					if (!Tokens.contains(prvch) && prvch != '.') {
						str.append("_");
					}
					str.append(Character.toLowerCase(ch));
					lastp = i + 1;
				}
				else if (startWithLetter && ch == '.') {
					str.append(name.substring(lastp, i));
					str.append('s');
					str.append(ch);
					lastp = i + 1;
				}
			}
			prvch = ch;
		}
		if (lastp < name.length()) {
			str.append(name.substring(lastp, name.length()));
		}
		return str.toString().replaceAll("^\\s*", "");
	}

	/**
	 * eg:<BR>
	 * "User.idTest = User.LogProfile sum'_= _aa..a' " = ><BR>
	 * "id_test = users.log_profile sum'_= _aa..a'";
	 * 
	 * @param name
	 * @return
	 */
	public static String toTableAttributes(String atr) {
		if (atr.length() < 1 || atr == null)
			return null;
		String[] strs = atr.split("=");
		if (strs.length > 2) {
			for (int i = 2; i < strs.length; i++)
				strs[1] = strs[1] + "=" + strs[i];

			return toTableName(strs[0].replaceFirst("\\w*\\.", "")).trim()
					+ " = " + toTableName(strs[1]).trim();
		}
		else {
			return toTableName(atr);
		}
	}

	public static String toUpateAttributes(String atr) {
		if (atr.length() < 1 || atr == null) { return null; }
		int ie = atr.indexOf("=");
		if (ie > 0) {
			String ta = atr.substring(0, ie);
			String newV = toTableName(atr.substring(ie));
			return ta + newV;
		}
		return toTableName(atr.replaceFirst("\\w*\\.", "")).trim();
	}

	/**
	 * 从当前指定字符串中提取对象名.
	 * 
	 * @param exp
	 * @return
	 */
	public static List<String> extractBeanName(String exp) {
		boolean notInQuote = true;
		List<String> lst = new LinkedList<String>();
		for (int i = 0; i < exp.length(); i++) {
			char ch = exp.charAt(i);
			if (ch == '\'') {
				notInQuote = !notInQuote;
			}
			if (notInQuote && Character.isUpperCase(ch)) {
				int start = i;
				int dot = -1;
				do {
					ch = exp.charAt(i);
					if (ch == '.') {
						dot = i;
					}
					if (Tokens.contains(ch)) {
						break;
					}
				} while (i++ < exp.length() - 1);
				if (dot > 0 && start + 1 < exp.length()) {
					lst.add(exp.substring(start, dot));
					i--;
				}
			}
		}
		return lst;
	}

	// private static final Pattern excuteFun = Pattern.compile(
	// "^\\s*select \\w+\\(.*\\)$", Pattern.CASE_INSENSITIVE);

	public static Set<String> extractEntityName(String sql) {

		return extractEntityName(sql, false);
	}

	private static Set<String> extractEntityName(String sql, boolean inPrvFrom) {

		if (sql.length() < 1)
			return new HashSet<String>();
		StringBuffer clause = new StringBuffer();
		SqlSentence fromClause = new SqlSentence();
		int braceCnt = 0;
		boolean inQuote = false;
		boolean inClause = false;
		char ch = '#';
		for (int i = 0; i < sql.length(); i++) {
			if (inQuote)
				continue;
			ch = sql.charAt(i);
			if (ch == '\'') {
				inQuote = !inQuote;
				continue;
			}
			else if (ch == '(') {
				inClause = inClause || braceCnt == 0;
				braceCnt++;
				if (braceCnt == 1)
					continue;
			}
			else if (ch == ')') {
				braceCnt--;
				inClause = braceCnt > 0;
				if (!inClause) {
					Collection<String> entities = extractEntityName(clause.toString().trim(), fromClause.isInFrom());
					if (entities.size() < 1 && fromClause.isInSelect())
						fromClause.addToRefs(fromClause.getWord());
					else fromClause.addToRefs(entities);
					clause = new StringBuffer();
					continue;
				}
			}
			if (inClause) {
				clause.append(ch);
			}
			else fromClause.pushChar(ch, inPrvFrom);
		}
		return fromClause.getRefs();
	}

	/**
	 * 提取表名和属性名， 以数
	 * 
	 * @param exp
	 * @return
	 */
	public static List<String> extractFullBeanAttributeName(String exp) {
		boolean notInQuote = true;
		List<String> lst = new LinkedList<String>();
		for (int i = 0; i < exp.length(); i++) {
			char ch = exp.charAt(i);
			if (ch == '\'') {
				notInQuote = !notInQuote;
			}
			if (notInQuote && Character.isUpperCase(ch)) {
				int start = i;
				int dot = -1;
				do {
					ch = exp.charAt(i);
					if (ch == '.') {
						dot = i;
					}
					if (Tokens.contains(ch)) {
						break;
					}
				} while (i++ < exp.length() - 1);
				if (dot > 0 && start + 1 < exp.length()) {
					lst.add(exp.substring(start, i));
					i--;
				}
			}
		}
		return lst;
	}

	/**
	 * attribute_of_Bean => attributeOfBean
	 * 
	 * @param name
	 * @return
	 */
	public static String toBeanName(String name) {
		if (name.length() < 1 || name == null)
			return name;
		StringBuffer str = new StringBuffer();
		int lastp = 0;
		boolean inQuote = false;
		char prvch = ' ';
		char ch = ' ';
		for (int i = 0; i < name.length(); i++) {
			ch = name.charAt(i);
			if (ch == '\'') {
				inQuote = !inQuote;
			}
			if (!inQuote && Character.isLetter(ch)) {
				if (prvch == '_') {
					str.append(name.substring(lastp, i - 1)
							+ Character.toUpperCase(ch));
					lastp = i + 1;
				}
			}
			prvch = ch;
		}
		if (lastp < name.length()) {
			if (ch == '_') {
				str.append(name.substring(lastp, name.length() - 1));
			}
			else {
				str.append(name.substring(lastp, name.length()));
			}
		}
		return str.toString().trim();
	}
}
